home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / uip / other / mlist.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-03-28  |  15.8 KB  |  804 lines

  1. #include "util.h"
  2. #include "mmdf.h"
  3. #include "ch.h"
  4. #include <pwd.h>
  5. #include <sys/stat.h>
  6. #include <signal.h>
  7. #include <stdio.h>
  8.  
  9. /*
  10.  *      Program to perform list additions and requests
  11.  *
  12.  *  Feb 84 Steve Kille    - initial coding
  13.  */
  14.  
  15. FILE *curfp;                             /* for alias file */
  16. char *basehelpfile = "mlist.help";
  17. char *helpfile;
  18.  
  19. char buf[LINESIZE];
  20.  
  21. char listname[LINESIZE];
  22. char filename[LINESIZE];
  23. char manager[LINESIZE];
  24. char *username;
  25. int realid;
  26. int curmode;
  27. int gotargs;
  28.  
  29. #define FREEMODE 0666
  30. #define PUBMODE 0744
  31. #define PRIVMODE 0644
  32. #define SECRMODE 0600
  33.  
  34. extern char *locmachine;
  35. extern char *supportaddr;
  36. extern char *cmddfldir;
  37.  
  38. extern char *compress();
  39. extern char *rindex();
  40. extern char *index();
  41. extern char *mktemp();
  42. extern char *strdup();
  43. extern char *getmailid();
  44. extern char *dupfpath();
  45.  
  46. main (argc, argv)
  47.     int argc;
  48.     char *argv[];
  49. {
  50.     mmdf_init (argv[0]);
  51.     user_init ();
  52.     arg_init (argc, argv);
  53.  
  54.     if (gotargs)
  55.     exit (OK);
  56.  
  57.     printf ("Welcome to the mailing list program\n");
  58.     FOREVER
  59.     {
  60.     printf ("\nType 'h' for list of lists, 'c' to create a list,\n");      printf ("'q' to quit, or the name of the list you wish to adjust");
  61.     printf ("\n\n>> ");
  62.     fflush (stdout);
  63.     if (gets (buf) == NULL)
  64.         exit(OK);
  65.     compress (buf, buf);
  66.     if (strlen (buf) == 0)
  67.         continue;
  68.     if (strlen (buf) == 1)
  69.     switch (buf [0])
  70.     {
  71.         case '\n':
  72.         continue;
  73.         case 'q':
  74.         printf ("Mail list program exiting\n");
  75.         exit (OK);
  76.         case 'c':
  77.         do_create ();
  78.         continue;
  79.         case 'h':
  80.         do_help ();
  81.         continue;
  82.     }
  83.     do_list (buf);
  84.     }
  85. }
  86. /* */
  87.  
  88. user_init ()
  89. {
  90.     struct passwd *pwd, *getpwuid();
  91.     char *getmailid();
  92.     int effid;
  93.  
  94.     umask (07000);                       /* set maks for creation */
  95.  
  96.     getwho (&realid, &effid);
  97.     if (realid == effid)
  98.     realid = 0;                     /*full priveledges to MMDF      */
  99.  
  100.     if ((pwd = getpwuid (realid)) == NULL ||
  101.     (username = getmailid (pwd -> pw_name)) == NULL)
  102.     {
  103.     printf ("Problem identifying user\n");
  104.     exit (NOTOK);
  105.     }
  106.     if (realid == 0)
  107.     printf ("You are a mail super-user\n");
  108.  
  109. }
  110. /* */
  111.  
  112.  
  113. arg_init (argc, argv)
  114.     int argc;
  115.     char *argv[];
  116. {
  117.     register int ind;
  118.  
  119.     helpfile = dupfpath(basehelpfile, cmddfldir);
  120.  
  121.     gotargs = FALSE;
  122.     for (ind = 1; ind < argc; ind++)
  123.     {
  124.     if (argv[ind][0] != '-')
  125.     {
  126.         gotargs = TRUE;
  127.         do_list (argv[ind]);
  128.     }
  129.     else
  130.         switch (argv[ind][1])
  131.         {
  132.         case 'f':
  133.             helpfile = strdup (argv[++ind]);
  134.             break;
  135.  
  136.         case 'c':
  137.             do_create ();
  138.             printf ("\nMail list program exiting\n");
  139.             exit (OK);
  140.  
  141.         case 'h':
  142.             do_help ();
  143.             printf ("\nMail list program exiting\n");
  144.             exit (OK);
  145.         default:
  146.             printf ("Invalid argument\n");
  147.             printf ("usage is: mlist [-ch] [-f file] [arg ....]\n");
  148.             exit (NOTOK);
  149.         }
  150.    }
  151. }
  152.  
  153. /* */
  154.  
  155. do_help ()
  156. {
  157.     FILE *fp;
  158.  
  159.     signal (SIGINT, SIG_IGN);
  160.  
  161.     if ((fp = fopen (helpfile, "r")) == NULL)
  162.     {
  163.     printf ("can't open helpfile '%s'\n", helpfile);
  164.     fflush (stdout);
  165.     return;
  166.     }
  167.  
  168.     while (fgets (buf, LINESIZE, fp) != NULL)
  169.     fputs (buf, stdout);
  170.     fflush (stdout);
  171.  
  172.     signal (SIGINT, SIG_DFL);
  173. }
  174.  
  175.  
  176. do_create ()
  177. {
  178.  
  179.     ml_1adr (TRUE, FALSE, (char *) 0, "Mailing list creation request",
  180.         supportaddr);
  181.     ml_txt ("Name of list\n");
  182.     printf ("Give name of list: ");
  183.     fflush (stdout);
  184.     if (gets (buf) == NULL)
  185.     exit(OK);
  186.     ml_txt (buf);
  187.     ml_txt ("\n\nFunction:\n");
  188.     printf ("Give a one line description of the list\n: ");
  189.     fflush (stdout);
  190.     if (gets (buf) == NULL)
  191.     exit(OK);
  192.     ml_txt (buf);
  193.     ml_txt ("\n\nDistributed from:\n");
  194.     printf ("Where is the list currently distributed from?\n: ");
  195.     fflush (stdout);
  196.     if (gets (buf) == NULL)
  197.     exit(OK);
  198.     ml_txt (buf);
  199.     ml_txt ("\n\nMaintainers\n");
  200.     printf ("Who will be responible for the list?\n");
  201.     printf ("You can give multiple addresses, but one must be a local ");
  202.     printf ("login\n: ");
  203.     fflush (stdout);
  204.     if (gets (buf) == NULL)
  205.     exit(OK);
  206.     ml_txt (buf);
  207.     printf ("processing message....\n");
  208.     fflush (stdout);
  209.     if (ml_end (OK) != OK)
  210.     {
  211.        printf ("\nproblem processing rquest.  Try again later\n");
  212.        return;
  213.     }
  214.     printf ("Your request has been passed to an administrator\n");
  215.     printf ("You will be notified in a short time when the list has been created\n");
  216.     printf ("You can then use this program to enter names into the list\n\n");
  217.     fflush (stdout);
  218. }
  219.  
  220. /* */
  221. do_list (list)
  222. char *list;
  223. {
  224.     char tmpbuf [LINESIZE];
  225.     int ismanager;
  226.     struct stat statbuf;
  227.     char *p,
  228.     *q;
  229.     int fd;
  230.     int i;
  231.  
  232.     strcpy (listname, list);
  233.  
  234.     ismanager = (realid == 0 ? TRUE : FALSE);
  235.     sprintf (manager, "%s-request", listname);
  236.     if (aliasfetch(TRUE, manager, buf, 0)!=OK)
  237.     strcpy (manager, supportaddr);
  238.     else if (!ismanager)
  239.     {
  240.     p = buf;
  241.     while ((q  = index (buf, ',')) != (char *) 0)
  242.     {
  243.         *q++ = '\0';
  244.         if (lexequ (p, username))
  245.         {
  246.         ismanager = TRUE;
  247.         printf ("You are a manager of list '%s'\n", listname);
  248.         }
  249.         p = q;
  250.     }
  251.     if (lexequ (p, username))
  252.     {
  253.         ismanager = TRUE;
  254.         printf ("You are a manager of list '%s'\n", listname);
  255.     }
  256.     }
  257.  
  258.     sprintf (tmpbuf, "%s-outbound", listname);
  259.     if (aliasfetch(TRUE, tmpbuf, buf, 0) != OK &&
  260.     aliasfetch(TRUE, listname, buf, 0) != OK)
  261.     {
  262.     printf ("list '%s' does not exist\n", listname);
  263.     return;
  264.     }
  265.  
  266.     if ((i = strindex (":include:", buf)) < 0)
  267.     {
  268.     printf ("alias '%s' is managed centrally\n", listname);
  269.     printf ("do you wish to mail a request to change the list");
  270.     if (confirm ())
  271.        u_req ();
  272.     return;
  273.     }
  274.  
  275.     q = index (&buf[i], '/');
  276.     p = index (q, '@');
  277.     if (p == (char *) 0)
  278.     {
  279.     if ((p = index (q, ',')) != (char *) 0)
  280.         *p = '\0';
  281.     strcpy (filename, q);
  282.     }
  283.     else
  284.     {
  285.     *p++ = '\0';
  286.     strcpy (filename, q);
  287.     if ((q = index (p, ',')) != (char *) 0)
  288.         *q = '\0';
  289.     if (ch_h2chan (p, 1) != OK)
  290.     {
  291.         printf ("Alias '%s' is expanded on machine '%s'\n",
  292.         listname,  p);
  293.         if (ismanager && realid != 0)
  294.         {
  295.         printf ("Log in to '%s' and try again\n", p);
  296.         fflush (stdout);
  297.         return;
  298.         }
  299.         printf ("do you wish to mail a request to change the list");
  300.         if (confirm ())
  301.            u_req ();
  302.         return;
  303.     }
  304.     }
  305.  
  306.  
  307.     if (stat (filename, &statbuf) < 0)
  308.     {                           /* create filewith correct modes */
  309.     if (!ismanager)
  310.     {
  311.         printf ("File for list '%s' can only be created by manager\n",
  312.             listname);
  313.         printf ("Do you want to send a message to the list manager");
  314.         if (confirm ())
  315.            u_req ();
  316.         return;
  317.     }
  318.     printf ("Manager creation of list file\n");
  319.     printf ("Do you want any other users to be able to add / remove\n");
  320.     printf ("their own names");
  321.  
  322.     if (confirm ())
  323.     {
  324.        printf ("And anyone else's name");
  325.        if (confirm ())
  326.         curmode = FREEMODE;
  327.        else
  328.         curmode =  PUBMODE;
  329.     }
  330.     else
  331.     {
  332.         printf ("Do you want other users to be able to see who is on the list");
  333.         if (confirm ())
  334.         curmode = PRIVMODE;
  335.         else
  336.         curmode = SECRMODE;
  337.     }
  338.     printf ("Creating file '%s'\n",  filename);
  339.     if ((fd = creat (filename, curmode)) < 0)
  340.     {
  341.         printf ("Unable to create filename '%s'\n", filename);
  342.         return;
  343.     }
  344.     close (fd);
  345.     }
  346.     else
  347.     {
  348.     curmode = (int) statbuf.st_mode;
  349.     curmode = curmode & 0777;
  350.  
  351.     if (!(ismanager || curmode == PUBMODE || curmode == FREEMODE))
  352.     {
  353.         printf ("list '%s' can only be updated by its manager\n",
  354.             listname);
  355.        if (curmode != SECRMODE)
  356.        {
  357.         printf ("do you want to see who is on the list");
  358.         if (confirm ())
  359.         {
  360.             if ((curfp = fopen (filename, "r")) == NULL)
  361.             {
  362.             printf ("Can't open file '%s'\n", filename);
  363.             return;
  364.             }
  365.             while (fgets (buf, LINESIZE, curfp) != NULL)
  366.             fputs (buf, stdout);
  367.             fclose (curfp);
  368.         }
  369.        }
  370.  
  371.        printf ("do you wish to mail a request to be added");
  372.        if (confirm ())
  373.           u_req ();
  374.         return;
  375.     }
  376.  
  377.     if ((curfp = fopen (filename, "r+")) == NULL)
  378.     {
  379.        printf ("Can't open file '%s'\n", filename);
  380.        return;
  381.     }
  382.     }
  383.  
  384.     printf ("Adjusting list '%s'\n", listname);
  385.     if (ismanager || curmode == FREEMODE)
  386.     master_adj ();
  387.     else
  388.     u_adj ();
  389.  
  390. }
  391.  
  392. /* */
  393. u_req ()
  394. {
  395.     ml_1adr (TRUE, FALSE, (char *) 0, "List change request", manager);
  396.     ml_txt ("Automatic request for addition to list: ");
  397.     ml_txt (listname);
  398.     printf ("You may ask for confirmation of any changes requested.\n");
  399.     printf ("Answering no to the next question will save the list ");
  400.     printf ("administrator's time.\n");
  401.     printf ("Do you require confirmation");
  402.     if (confirm ())
  403.     ml_txt ("\n\nConfirmation requested");
  404.     else
  405.     ml_txt ("\n\nConfirmation NOT requested");
  406.     ml_txt ("\n\nNames:\n\n");
  407.     printf ("sending request to list manager (%s)\n", manager);
  408.     printf ("specify names to be added or removed from list '%s'\n",
  409.         listname);
  410.     printf ("end with .<CR> on a newline\n");
  411.     while (fgets (buf, LINESIZE, stdin) != NULL)
  412.     if (strlen (buf) == 2 && buf[0] == '.')
  413.         break;
  414.     else
  415.         ml_txt (buf);
  416.    printf ("Processing message....\n");
  417.    fflush (stdout);
  418.    if (ml_end (OK) != OK)
  419.     printf ("problem sending request\n");
  420.    else
  421.    {
  422.     printf ("Your request has been sent\n");
  423.     printf ("It will be processed in the next few days\n");
  424.    }
  425. }
  426.  
  427. u_adj ()
  428. {
  429.     printf ("would you like a listing of this list");
  430.     if (confirm ())
  431.     {
  432.     if ((curfp = fopen (filename, "r")) == NULL)
  433.     {
  434.         printf ("Can't open file '%s'\n", filename);
  435.         return;
  436.     }
  437.     while (fgets (buf, LINESIZE, curfp) != NULL)
  438.         fputs (buf, stdout);
  439.     fclose (curfp);
  440.     }
  441.  
  442.     printf ("Do you want to add or remove your name");
  443.     if (!confirm ())
  444.     {
  445.         printf ("Do you want to send a request to the list maintainer\n");
  446.         if (confirm ())
  447.         u_req ();
  448.         else
  449.         printf ("sorry, no other options for mortals\n");
  450.         return;
  451.     }
  452.  
  453.     if (u_inlist (username))
  454.     {
  455.     printf ("You (%s) are already in this list\n",
  456.         username);
  457.     printf ("do you wish to be removed? ");
  458.     if (confirm ())
  459.         u_remove (username);
  460.     }
  461.     else
  462.     {
  463.     printf ("You (%s) are not in this list\n",
  464.         username);
  465.     printf ("do you wish to be added? ");
  466.     if (confirm ())
  467.         u_add (username);
  468.     }
  469. }
  470.  
  471. /* */
  472.  
  473. master_adj ()
  474. {
  475. char tmpbuf [LINESIZE];
  476. char ch;
  477.  
  478.     v_init ();
  479.     printf ("You are in list manager mode\n");
  480.     FOREVER
  481.     {
  482.     printf ("print list (p), verify list (v), add user (a), remove ");
  483.     printf ("user (r), quit (q)?\n");
  484.     printf ("default is assumed to be user name to be added\n\n>>> ");
  485.     fflush (stdout);
  486.     if (gets (tmpbuf) == NULL){
  487.         v_end ();
  488.         exit(OK);
  489.     }
  490.     compress (tmpbuf, tmpbuf);
  491.     if(strlen(tmpbuf) > 1)
  492.         ch = 'A';
  493.     else
  494.         ch = uptolow (tmpbuf[0]);
  495.     switch (ch)
  496.     {
  497.         case '\0':
  498.         case '\n':
  499.         continue;
  500.         case 'q':
  501.         v_end ();
  502.         return;
  503.         case 'p':
  504.         if ((curfp = fopen (filename, "r")) == NULL)
  505.         {
  506.             printf ("Can't open file '%s'\n", filename);
  507.             return;
  508.         }
  509.         while (fgets (tmpbuf, LINESIZE, curfp) != NULL)
  510.             fputs (tmpbuf, stdout);
  511.         fclose (curfp);
  512.         break;
  513.         case 'v':
  514.         v_list ();
  515.         break;
  516.         case 'a':
  517.         printf ("give username to be added: ");
  518.         if (gets (tmpbuf) == NULL){
  519.             v_end ();
  520.             exit(OK);
  521.         }
  522.         compress (tmpbuf, tmpbuf);
  523.         if (u_inlist (tmpbuf))
  524.             printf ("User '%s' already in list\n", tmpbuf);
  525.         else
  526.             if (verify (tmpbuf))
  527.             u_add (tmpbuf);
  528.             else
  529.             printf ("Illegal address '%s'\n", tmpbuf);
  530.         break;
  531.  
  532.         case 'r':
  533.         printf ("give username to be removed: ");
  534.         if (gets (tmpbuf) == NULL){
  535.             v_end ();
  536.             exit(OK);
  537.         }
  538.         compress (tmpbuf, tmpbuf);
  539.         if (!u_inlist (tmpbuf))
  540.             printf ("User '%s' not in list\n", tmpbuf);
  541.         else
  542.             u_remove (tmpbuf);
  543.         break;
  544.  
  545.         default:
  546.         if (u_inlist (tmpbuf))
  547.             printf ("User '%s' already in list\n", tmpbuf);
  548.         else
  549.             if (verify (tmpbuf))
  550.             {
  551.             u_add (tmpbuf);
  552.             }
  553.             else
  554.             printf ("Illegal address '%s'\n", tmpbuf);
  555.         break;
  556.  
  557.     }
  558.     }
  559. }
  560.  
  561. /* */
  562. u_inlist (user)
  563. char *user;
  564. {
  565.  
  566.     if ((curfp = fopen (filename, "r")) == NULL)
  567.     {
  568.     printf ("Can't open file '%s'\n", filename);
  569.     return (FALSE);
  570.     }
  571.     while (fgets (buf, LINESIZE, curfp) != NULL)
  572.     {
  573.     buf [strlen(buf) - 1] = '\0';
  574.     if (lexequ (user, buf))
  575.     {
  576.         fclose (curfp);
  577.         return (TRUE);
  578.     }
  579.     }
  580.     fclose (curfp);
  581.     return (FALSE);
  582. }
  583.  
  584.  
  585. u_add (user)
  586. char *user;
  587. {
  588.  
  589.     if ((curfp = fopen (filename, "a")) == NULL)
  590.     {
  591.        printf ("Can't open file '%s'\n", filename);
  592.        return;
  593.     }
  594.     printf ("adding user '%s'\n", user);
  595.     fputs (user, curfp);
  596.     fputc ('\n', curfp);
  597.     fclose (curfp);
  598. }
  599.  
  600. u_remove (user)
  601. char *user;
  602. {
  603.     char *template = "al.XXXXXX";
  604.     char fpath [LINESIZE];
  605.     char *cp;
  606.     FILE  *fp;
  607.     int  fd;
  608.  
  609.                 /* first make temp file in same dir */
  610.     strcpy (fpath, filename);
  611.     cp = rindex (fpath, '/');
  612.     if (cp++ == 0)
  613.     fpath [0] = '\0';
  614.     else
  615.     *cp = '\0';
  616.     strcat (fpath, template);
  617.     mktemp (fpath);
  618.     if ((fd = creat (fpath, curmode)) < 0)
  619.     {
  620.     printf ("Can't create temp file '%s'\n", fpath);
  621.     return;
  622.     }
  623.     if ((fp = fdopen (fd, "w")) == NULL)
  624.     {
  625.     printf ("Can't open temp file '%s'\n", fpath);
  626.     return;
  627.     }
  628.  
  629.  
  630.     if ((curfp = fopen (filename, "r")) == NULL)
  631.     {
  632.     printf ("Can't open file '%s'\n", filename);
  633.     return;
  634.     }
  635.     while (fgets (buf, LINESIZE, curfp) != NULL)
  636.     {
  637.     buf [strlen(buf) - 1] = '\0';
  638.     if (lexequ (buf, user) && strlen (buf) == strlen (user))
  639.         printf ("removing user '%s'\n", buf);
  640.     else
  641.     {
  642.         fputs (buf, fp);
  643.         fputc ('\n', fp);
  644.     }
  645.     }
  646.     fclose (curfp);
  647.     fclose (fp);
  648.     unlink (filename);
  649.     link (fpath, filename);
  650.     unlink (fpath);
  651. }
  652.  
  653.  
  654. v_list ()                       /* go throughlist and verify    */
  655. {
  656.     int  donesofar;
  657.     int i;
  658.     char tmpbuf [LINESIZE];
  659.  
  660.  
  661.     if ((curfp = fopen (filename, "r")) == NULL)
  662.     {
  663.        printf ("Can't open file '%s'\n", filename);
  664.        return;
  665.     }
  666.     donesofar = 0;
  667.     while (fgets (tmpbuf, LINESIZE, curfp) != NULL)
  668.     {
  669.     tmpbuf [strlen(tmpbuf) - 1] = '\0';
  670.     if (!verify (tmpbuf))
  671.     {
  672.         printf ("Remove user '%s'", tmpbuf);
  673.         if (confirm ())
  674.         {
  675.         fclose (curfp);
  676.         u_remove (tmpbuf);
  677.         if ((curfp = fopen (filename, "r")) == NULL)
  678.         {
  679.             printf ("Can't open file '%s'\n", filename);
  680.             return;
  681.         }
  682.         for (i = 0; i < donesofar; i++)
  683.             if (fgets (tmpbuf, LINESIZE, curfp) == NULL)
  684.             continue;
  685.         continue;
  686.         }
  687.     }
  688.     donesofar++;
  689.     }
  690. }
  691.  
  692.  
  693. /* */
  694.                 /* address check stuff          */
  695.  
  696.  
  697. v_init ()
  698. {
  699.     struct rp_bufstruct thereply;
  700.     int     len;
  701.  
  702.     if (rp_isbad(mm_init()) || rp_isbad(mm_sbinit()) ||
  703.         rp_isbad(mm_winit ((char *)0, "vm", "mmdf")) ||
  704.         rp_isbad(mm_rrply( &thereply, &len ))) {
  705.         printf("Cannot initialize address checking\n");
  706.         mm_end (NOTOK);
  707.         exit( 8 );
  708.     } else if (rp_isbad(thereply.rp_val)) {
  709.         printf ("verify: %s\n", thereply.rp_line);
  710.         mm_end (NOTOK);
  711.         exit(9);
  712.     }
  713.  
  714. }
  715.  
  716. v_end ()
  717. {
  718.     mm_end (NOTOK);
  719. }
  720.  
  721. verify (addr)
  722. char    *addr;
  723. {
  724.     struct rp_bufstruct thereply;
  725.     int     len;
  726.  
  727.     printf("%s: ", addr);
  728.     fflush(stdout);
  729.  
  730.     if (rp_isbad (mm_wadr ((char *)0, addr))) {
  731.         if( rp_isbad( mm_rrply( &thereply, &len ))) {
  732.             printf ("Mail system problem\n");
  733.             mm_end (NOTOK);
  734.             exit( 8 );
  735.         } else {
  736.             printf ("%s\n", thereply.rp_line);
  737.             return (FALSE);
  738.         }
  739.  
  740.     } else {
  741.         if( rp_isbad( mm_rrply( &thereply, &len ))) {
  742.             printf ("Mail system problem\n");
  743.             mm_end (NOTOK);
  744.             exit (7);
  745.         } else if( rp_isbad( thereply.rp_val )) {
  746.             printf ("%s\n", thereply.rp_line);
  747.             return (FALSE);
  748.         } else {
  749.             printf ("OK\n");
  750.             return (TRUE);
  751.         }
  752.     }
  753.     /*NOTREACHED*/
  754. }
  755.  
  756. /* */
  757.                 /*  various utilities                   */
  758.  
  759. confirm ()
  760. {
  761.     register char   c;
  762.  
  763.  
  764.     printf (" [Confirm] ");
  765.     fflush (stdout);
  766.  
  767.     c = ttychar ();
  768.  
  769.     switch (c)
  770.     {
  771.     case 'Y':
  772.     case 'y':
  773.     case '\n':
  774.         printf ("yes\r\n");
  775.         fflush (stdout);
  776.         return (TRUE);
  777.  
  778.     case 'N':
  779.     case 'n':
  780.         printf ("no\r\n");
  781.         return (FALSE);
  782.     default:
  783.         printf ("Type yes or no.  <CR> defaults to yes\n");
  784.         return (confirm ());
  785.     }
  786. }
  787.  
  788.  
  789. ttychar ()
  790. {
  791.     register int    c;
  792.  
  793.     fflush (stdout);
  794.     fgets (buf, LINESIZE,  stdin);
  795.     c = buf[0];
  796.  
  797.     c = toascii (c);    /* get rid of high bit */
  798.  
  799.     if (c == '\r')
  800.     c = '\n';
  801.  
  802.     return (c);
  803. }
  804.